home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
dorskel2.arc
/
DOORSKEL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-05
|
27KB
|
1,005 lines
/**********************************************/
/* */
/* XBBS Door Skeleton -- TC 2.0/MSC 6.0a code */
/* Copyright (c) 1990/91 by M. Kimes */
/* All Rights Reserved */
/* May be freely used for >>>FREE<<< programs */
/* as long as you don't try to save any souls */
/* (nasty habit) */
/* */
/**********************************************/
/* Always include this module (with appropriate #defines) */
/**************************************************************************
Miscellaneous notes:
#define XBBS and the program will be compiled to read ONLINE.XBS
#define DORINFO and the program will be compiled to read DORINFO?.DEF
#define both and first ONLINE.XBS will be read, then DORINFO?.DEF
(don't know why you'd wanna do that)
#define neither and all info must come from command line
#define FINDUSER and a routine to find a given user (by name) will
be compiled in (finduser()) for XBBS' USERS.BBS
#define NOREADFILE and the file reader routine (readtext()) will NOT
be compiled
#define DISABLEBREAK to disable CTRL-BREAK/CTRL-C
#define DIALTRANS to include a dial_trans function for modem dialing,
etc.
set chars to be unsigned by default
recommend large model (recompile screen2.asm and ansi.asm if other)
this code requires a FOSSIL for serial i/o--see function fossil()
My indenting style is thanks to Mike Looney who taught me everything
he knows. ;^D
***************************************************************************/
#include "doorskel.h" /* DOORSKEL's include file */
/* Conditional global variables created here */
#ifdef XBBS
struct _config conf;
struct _user user;
word userno;
struct time timeon;
char timer_off;
word hold_time;
char age;
char pages;
struct _mboard mboard;
struct _fboard fboard;
struct _events event[10];
char variable[10][82];
ulong starter;
#endif
/* Global variables created here -- NOTE DEFAULTS! */
char debug_mode = 0;
char graphics = 0;
time_t timelimit;
word baud = 0;
char numlines = 24;
word seclvl = 5;
time_t startt = 0;
char sysopin = 0;
char fastANSI = 1;
char commport = 0;
char logfile[133] = "XBBS.LOG";
char username[36] = "A. Ghost";
char width = 80;
char chatting = 0;
char chatted = 0;
char nodenumber = 1;
char system_name[64] = "";
char sysop[36] = "";
/* These are tied to the screen2.asm module */
int maxx,maxy; /* size of local screen */
word videomethod,vbase;
char current_color = 7,cls_clr = 7;
int FAR *vseg; /* this one we use for internal dputs() replacement */
#ifdef __TURBOC__
extern unsigned _Cdecl _stklen = 8192; /* Stack length; adjust if req'd */
/* note MSC adjusts stack at compile or link time */
#endif
void _cdecl main (int argc,char **argv) {
register int x;
char *p;
set_mtask(); /* see mtask.c */
/* Please leave this next line in as a courtesy...thanks */
fputs(
"\x1b[2J\x1b[0;2;37m\x1b[1;1H\r\04 Built from M. Kimes' DOORSKEL kit v1.03.\n",
stdout);
srand((unsigned)time(NULL));
videomethod = 0; /* default direct video */
vbase = (vmode() == 7 ? 0xb000: 0xb800); /* find base address of video ram */
vseg = MK_FP(vbase,0); /* address of video ram as pointer */
timelimit = time(NULL) + (30L * 60L); /* default 30 min timelimit */
set_screen_size(); /* find screen size */
setcoords(0,0,maxx - 1,maxy - 2); /* change if you want more than one */
/* status line or whatever */
#ifdef DISABLEBREAK
break_handler(0);
#endif
if (argc == 2 && !stricmp(argv[1],"H")) { /* check for help request */
printinfo(); /* FILENAME H on command line */
printhelp();
exit(0);
}
set_raw(); /* for output speed */
atexit(deinitialize);
/* read exit files per conditional compilation */
#ifdef XBBS
readconfig();
getonline();
#endif
#ifdef DORINFO
readinfo();
#endif
for (x = 1;x < argc;x++) { /* process command line args */
ReSwitch:
switch (toupper(*argv[x])) {
case '-': /* ignore common "switch" chars */
case '/': memmove(argv[x],&argv[x][1],strlen(argv[x]));
goto ReSwitch;
case 'F': fastANSI = 0; /* turn INT 29H fastwriting off */
break;
case 'U': strncpy(username,&argv[x][1],36); /* user's name */
username[35] = 0;
break;
case 'N': nodenumber = (char)atoi(&argv[x][1]); /* node number */
break;
case 'L': numlines = (char)atoi(&argv[x][1]); /* length of user's screen */
break;
case 'W': width = (char)atoi(&argv[x][1]); /* width of user's screen */
break;
case 'B': baud = (word)atoi(&argv[x][1]); /* current baud rate */
break; /* 0 = local only */
case 'G': if(atoi(&argv[x][1])) graphics = 1; /* ANSI on if non-zero */
break;
case 'C': commport = (char)atoi(&argv[x][1]); /* 0 = COM1 */
break;
case 'S': seclvl = atoi(&argv[x][1]); /* security level */
break;
case 'T': timelimit = time(NULL) + ((atol(&argv[x][1])) * 60L); /* time in minutes */
break;
case 'M': videomethod = atoi(&argv[x][1]); /* for direct screen write control; 0 = direct, 1 = bios */
break;
case '!': debug_mode = 1; /* turn on debug printing */
break;
case 'X': strcpy(logfile,&argv[x][1]); /* set logfile */
break;
/********* add any special command switches here **********/
/********* remember to add help in printhelp() below ******/
default: fputs("\nUnknown argument `",stdout);
fputs(argv[x],stdout);
fputs("'\n",stdout);
my_sleep(1);
}
}
setfastansi(fastANSI);
fossil(INIT,0); /* activates FOSSIL driver */
cls(); /* clear our screen and theirs */
printg("\x1b[0;1;37m"); /* default colors for ANSI users */
p = PROGRAM_NAME; /* transmit program name */
if(baud) while (*p++) while(!fossil(TRANSMIT,*p)) carrchk();
printinfo(); /* print local program id info */
printm("\r\n");
mainloop(); /* jumps to your "program" in DOORSKL4.C */
/* If you want to change parameters in CONFIG.BBS or ONLINE.XBS,
* change them, then call saveconfig() or prepare() here or in
* deinitialize() (only for XBBS use)
*/
}
void _fastcall printhelp (void) { /* Print help screen--edit to taste
Add to as required */
fputs(" Command line arguments:\n"
"L<screen lines>\n"
"N<nodenumber>\n"
"U<user name>\n"
"W<screen width>\n"
"T<time in minutes>\n"
"B<baudrate (0-38400...?)>\n"
"G<graphics (0 or 1)>\n"
"C<commport (0=COM1)>\n"
"S<security level>\n"
"M<mode (0=direct video, 1=BIOS, 2=DOS)>\n"
"X<filename> (Log File)\n"
"F (Fast ANSI writes (through INT 29H) off)\n"
"! (Debug mode on)\n",stdout);
#ifdef DORINFO
fputs(" Requires a DORINFO?.DEF file\n",stdout);
#endif
#ifdef XBBS
fputs(" Requires XBBS ONLINE.XBS and CONFIG.BBS files\n",stdout);
#endif
}
#ifdef DISABLEBREAK
void _cdecl break_handler (int sigl) { /* guess */
signal(SIGINT,SIG_IGN);
/* do whatever you want */
signal(SIGINT,break_handler);
return;
}
#endif
void _fastcall chat (void) { /* Cheap chat-mode */
char a[3];
union REGS r;
printg("\x1b[0;1;33m");
printm("\r\n\r\nChat mode engaged\r\n\r\n");
while (chatting) {
*a = inkey();
a[1] = 0;
if (chatting) {
#ifdef __TURBOC__
_AH = 3;
_BH = 0;
geninterrupt(16);
#else
r.h.ah = 3;
r.h.bh = 0;
int86(16,&r,&r);
#endif
if (*a == '\r') printm("\r\n");
#ifdef __TURBOC__
if ((*a == '\r') || (*a == ' ' && _DL > maxx - 10)) printm("\r\n");
#else
if((*a == '\r') || (*a == ' ' && r.h.dl > maxx - 10)) printm("\r\n");
#endif
else printm(a);
}
}
printm("\r\n\r\nChat mode ended\r\n\r\n");
chatted++;
}
void _fastcall printg (char *text) { /* Print only if user has graphics set */
if(graphics) printm(text);
}
char _fastcall inkey (void) { /* like BASIC's INKEY$ local and remote */
char arg = 0;
union REGS rg;
rg.h.ah = 11;
int86(0x21,&rg,&rg); /* check DOS for key waiting */
if (rg.h.al) { /* key is waiting */
rg.h.ah = 8;
int86(0x21,&rg,&rg);
if (rg.h.al) return((char)(rg.h.al)); /* got normal key */
rg.h.ah = 8; /* else got extended key */
int86(0x21,&rg,&rg);
arg = specialkey(rg.h.al);
if (arg) return (arg); /* is a non-reserved extended key */
}
if (baud) {
arg = carrchk(); /* check carrier and whether a key is available */
if (!(arg & 1)) return 0; /* no key available */
fossil(RECVWAIT,arg);
if(!arg || arg == '\x1b') return specialmod(arg); /* ANSI or Doorway key else normal key */
return arg;
}
getxbbstime(); /* check timeleft, update status line */
pause_mtask(); /* give up timeslice */
return 0; /* return "no key" */
}
char _fastcall specialmod (char wuz) {
/* process "extended" keys and ANSI cursor keys */
char arg;
clock_t t1;
t1 = timerset(250L);
while(!timeup(t1)) {
arg = carrchk();
if (arg & 1) break; /* 1/4 sec for next part of key sequence */
}
if (!(arg & 1)) return 0;
arg = (fossil(RECVWAIT,arg));
if(!wuz) return (arg | 128); /* "Doorway" key */
if (arg != '[') return 0; /* it's a bad ANSI sequence */
t1 = timerset(250L); /* we have <-[ so far... */
while(!timeup(t1)) {
arg = carrchk();
if(arg & 1) break;
}
arg = carrchk();
if(!(arg & 1)) return 0;
arg = (fossil(RECVWAIT,arg));
if((arg != '1') && (arg != 'A') && (arg != 'B') &&
(arg != 'C') && (arg != 'D') && (arg != 'K'))
return 0; /* not an ANSI sequence we recognize */
/* note internal representation of cursor keys */
if(arg == 'A') return 1; /* UP */
if(arg == 'B') return 2; /* DOWN */
if(arg == 'C') return 3; /* RIGHT */
if(arg == 'D') return 4; /* LEFT */
if(arg == 'K') return 211; /* DELETE */
/* some terms send <-[1A, some just send <-[A; this checks former */
t1 = timerset(250L);
while(!timeup(t1)) {
arg = carrchk();
if (arg & 1) break;
}
arg = carrchk();
if(!(arg & 1)) return 0;
arg = (fossil(RECVWAIT,arg));
if((arg != 'A') && (arg != 'B') && (arg != 'C') &&
(arg != 'D')) return 0;
if(arg == 'A') return 1;
if(arg == 'B') return 2;
if(arg == 'C') return 3;
if(arg == 'D') return 4;
return 0;
}
char _fastcall specialkey (char a) {
/* this function processes extended local keys. add your own... */
/* a is second half of scan code (0 + a) */
switch (a) {
case 45:cls(); /* ALT-Q for example, 0 + 45 */
exit(0); /* QUIT DOOR */
case 35: /* HANG UP */
fossil(DTR,DOWN);
exit(1);
case 46: /* chat mode */
chatting = 1 - chatting;
if(chatting) chat();
return 0;
case 36: /* SysOp SHELL */
cls();
printm(" \x1b[0m\r\nThe SysOp has jumped to DOS...please wait...\r\n");
fossil(FLUSHOUT,0);
pause_mtask();
spawnit(getenv("COMSPEC"));
printm("\r\nThe SysOp has returned...please continue...\r\n");
my_sleep(1);
return(0);
case 131: /* MORE TIME... ALT + */
timelimit += 60L;
return 0;
case 130: /* LESS TIME... ALT - */
if (timelimit - getxbbstime() < 60L) timelimit = time(NULL);
else timelimit -= 60L;
return 0;
}
return (a | 128); /* return "extended key" */
}
void _fastcall cls (void) { /* like BASIC's CLS */
char *clr_string = "\x1b[0m\x1b[2J";
/* first clear remote */
if(!graphics) clr_string = "\xc";
if(baud) {
while (*clr_string++) {
while(!fossil(TRANSMIT,*clr_string)) carrchk();
}
}
/* then clear local */
fputs("\x1b[0m\x1b[2J",stdout);
print_stat(); /* replace erased status line */
}
char _fastcall fossil (char function,char arg) {
/* handles most common fossil calls */
/* see FOSSIL.DOC or FSC-0015 for more info on FOSSIL drivers */
union REGS rg;
if(!baud) return 0;
if (function == FLUSHOUT) {
do {
carrchk();
rg.h.ah = 3;
rg.x.dx = commport;
int86(20,&rg,&rg);
} while (!(rg.h.ah & 64));
return(0);
}
if (function == WATCHDOG) rg.h.al = arg;
else if (function == DTR) rg.h.al = arg;
else if (function == TRANSWAIT) rg.h.al = arg;
else if (function == TRANSMIT) rg.h.al = arg;
else if (function == ONOFF) rg.h.al = arg;
rg.x.dx = commport;
rg.h.ah = function;
int86(20,&rg,&rg);
if (function == INIT) {
if (rg.x.ax != INITOK) { /* ARGH! couldn't initialize FOSSIL */
fputs("\nFossil not responding...RTFM.\n",stdout);
exit (3);
}
return (0);
}
if (function == GETSTAT) {
arg = rg.h.ah;
if (rg.h.al & 128) {
arg |= 128;
return (arg);
}
arg &= 127;
return (arg);
}
if (function == RECVWAIT) return rg.h.al;
if (function == TRANSMIT) return (char)rg.x.ax;
return (0);
}
void _cdecl deinitialize (void) { /* deinit fossil, etc. at exit */
fossil(FLUSHOUT,0);
fossil (DEINIT,0);
fcloseall();
set_cooked();
/* put other atexit stuff you need here... */
printm("\r\n");
fputs("\x1b[0;2;37m\n",stdout);
}
/* generic input routine -- see types in doorskel.h */
char * _fastcall genin (char length, /* maximum length of user input */
char password, /* "shroud" input echo if non-zero */
char caps, /* force input to uppercase if non-zero */
char hot, /* "hot" input if non-zero */
char type) { /* type of input -- see doorskel.h */
static char input[257];
int x = 0;
char one = 0;
char randchr[2];
length--; /* note */
AfterChat:
strset(input,0);
startt = getxbbstime();
while ((getxbbstime() - startt) < 241 || (chatted != 0)) {
one = inkey();
if (one == '\r') break;
Nogo:
if (one == 8) {
if (x > 0) {
printm(BACKSPACE);
input [--x]=0;
if ((type==PHONE) && ((x==2) || (x==5))) printm(BACKSPACE);
if ((type==DATE) && ((x==3) || (x==5))) printm(BACKSPACE);
}
continue;
}
if (type==ARROWS) {
switch (one) {
case 1:
case 2:
case 3:
case 4:
case 5:
case '?':
case 27:
case 11: *input=one;
return (input);
case 13: *input=0;
return (input);
}
if (isprint(one)) {
*input=toupper(one);
return (input);
}
continue;
}
if ((caps) || (type==YESNO) || (type==YESNOM) || (type==FLE) || (type==FLEW) || (type==FLEPW) || (type==FLEP) || (type==FLENX)) one=toupper(one);
if (x <= length) {
if(type==HYPER && (one==27 || one==11)) goto BreakOutOfIt;
if(type==HYPER && graphics && one<6 && one!=3) goto BreakOutOfIt;
if (type==NAME) {
if((isalpha(one)==0) && (one!=' ') && (one!='.') && (one!='-') || (x==0 && one==' ')) continue;
if ((one==' ') && (strchr(input,' ')!=NULL)) continue;
}
if (type==NEAT) {
if((isalnum(one)==0) && (one!=' ') || (x==0 && one==' ')) continue;
}
if ((type==NEAT) || (type==NAME)) {
if(x==0) {
one=toupper(one);
}
else one=tolower(one);
}
if((type==NEAT) || (type==NAME)) {
if((x>0) && ((input[x-1]==' ') || (input[x-1]=='.') || (input[x-1]=='-'))) one=toupper(one);
}
if ((type==SUBJECT) && (x==0)) one=toupper(one);
if ((type==SUBJECT) && (isprint(one)==0)) continue;
if ((type==ALLL) && (isprint(one)==0)) continue;
if ((type==ALLL) && (one==127)) one=8;
if ((type==ALPHA) && (isalpha(one)==0) && (one!=' ')) continue;
if (((type==NUM) || (type==PHONE) || (type==DATE)) && (isdigit(one)==0)) continue;
if ((type==ALPHANUM) && (isalnum(one)==0) && (one!=' ')) continue;
if (((type==YESNO) || (type==YESNOM)) && (one!='Y' && one!='N')) continue;
if (type==FLE) {
if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&/",one))) continue;
}
if (type==FLENX) {
if ((isalnum(one)==0) && (!strchr("_-+=!@#$%^&/",one))) continue;
}
if (type==FLEP) {
if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&/\\:",one))) continue;
}
if (type==FLEW) {
if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&/?*",one))) continue;
}
if (type==FLEPW) {
if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&/?*\\:",one))) continue;
}
if ((type==FLE) || (type==FLEP) || (type==FLEW) || (type==FLEPW)) {
if ((one=='.') && (strchr(input,'.')!=NULL)) continue;
}
BreakOutOfIt:
;
}
if (chatted > 0) { /* allow for chat having interrupted us */
chatted = 0;
goto AfterChat;
}
if ((one!=0) && (x <= length)) {
input[x]=one;
input[++x]=0;
if (type==YESNOM) {
return(input);
}
if (password == 0) printm(&input[x - 1]);
if (password != 0) {
randchr[0] = (rand() % 10) + 33;
randchr[1] = 0;
printm(randchr);
}
if ((type == PHONE) && ((x == 3) || (x == 6))) printm("-");
if ((type == DATE) && ((x == 4) || (x == 6))) printm("/");
AfterCtrl:
if ((hot != 0)&&(x >= length)) {
return (input);
}
startt = getxbbstime();
}
}
if (chatted) {
chatted=0;
goto AfterChat;
}
if ((getxbbstime() - startt) > 240) {
fputs("\nUser time-out...\n",stdout);
exit (2);
}
return (input);
}
char _fastcall carrchk (void) { /* Checks for carrier */
union REGS rg;
if (baud) {
rg.x.dx = commport;
rg.h.ah = GETSTAT;
int86(20,&rg,&rg);
if (!(rg.h.al & 128)) { /* no carrier */
my_sleep(1); /* delay a sec, try again */
rg.x.dx = commport;
rg.h.ah = GETSTAT;
int86(20,&rg,&rg);
if (!(rg.h.al & 128)) { /* still no carrier, outta here */
fossil(DTR,DOWN);
baud=0;
fputs("\n\04 Lost carrier...\n",stdout);
exit (1);
}
}
return (rg.h.ah); /* can be inspected to see if input char is ready */
}
return 0;
}
void _fastcall hitreturn (void) { /* pause until [Enter] is pressed */
register word x;
startt = getxbbstime();
printm("\r\n[Enter] to continue...");
while ((getxbbstime() - startt) < 241L) {
if (inkey() == '\r') goto HeDid;
}
fputs("\n\04User time-out...\n",stdout); /* dump lazy bum */
exit (2);
HeDid:
for(x = 0;x < 22;x++) printm(BACKSPACE); /* Back over prompt */
}
time_t _fastcall getxbbstime (void) {
/* checks user time, updates mins remaining on status line, warns
user of impending out-of-time, etc. returns current time_t */
static time_t xbbs_time,lasttime;
static int warned = 0,x,y;
xbbs_time = time(NULL);
if (timelimit < xbbs_time + 120L && !warned) {
warned++;
printfm("\x1b[s\x1b[%d;1H\x1b[K\x1b[0;1;37m",maxy - 2);
printfm("\07WARNING: %ld mins left!!!\x1b[u",(timelimit - xbbs_time) / 60L);
fossil(FLUSHOUT,0);
}
if (timelimit > xbbs_time + 120L && warned) warned = 0;
if (timelimit < xbbs_time) {
timelimit = xbbs_time + 240L;
printfm("\x1b[%d;1H\x1b[K\x1b[0;1;37mSorry, time to logoff...",maxy - 2);
fossil(FLUSHOUT,0);
exit(0);
}
if(lasttime != xbbs_time) {
curr_cursor(&x,&y);
current_color = 7 * 16;
dprintf(maxx - 6,maxy,"%-5ld",(timelimit - xbbs_time) / 60L); /* note method of */
lasttime = time(NULL); /* determining time */
cursor(x,y); /* remaining... */
}
return xbbs_time;
}
void _fastcall printinfo (void) { /* Just prints prog info locally */
fprintf(stderr," %s\n\04 %s\n\04 Compiled: %s %s\n",PROGRAM_NAME,COPY_RIGHT,__DATE__,__TIME__);
}
char * _fastcall fidodate (void) { /* Builds a _correct_ Fido(tm) datestring */
/* this is here because sooooo many people SCREW IT UP */
/* this is the RIGHT way to make a Fido date string */
/* see FTS-0001 for more info */
#ifdef __TURBOC__
char months[12][4]={ /* note; newer versions of TC have strftime... */
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
static char fdate[20];
struct date dos_date;
struct time dos_time;
/* 26 Jul 89 06:23:47 */
getdate(&dos_date);
gettime(&dos_time);
sprintf(fdate,"%02hu %s %02d %02hu:%02hu:%02hu",dos_date.da_day,months[dos_date.da_mon-1],dos_date.da_year%100,dos_time.ti_hour,dos_time.ti_min,dos_time.ti_sec);
/* ^^ */
#else
static char fdate[32];
time_t t;
t = time(NULL);
strftime(fdate,31,"%d %a %y %H:%M:%S",localtime(&t));
/* ^^ */
#endif
return(fdate);
}
void _cdecl debug_print (char *string,...) { /* Local-only messages, only
displayed if debug-mode is
turned on by ! argument */
word tempbaud;
static char buffer[318];
va_list ap;
va_start(ap,string);
vsprintf(buffer,string,ap);
va_end(ap);
if(debug_mode) { /* note simple method of temporarily */
tempbaud = baud; /* shutting out remote... */
baud = 0;
printm(buffer);
baud = tempbaud;
}
}
int _cdecl printfm (char *string,...) { /* Like printf() for local
and remote */
static char buffer[318];
int val;
va_list ap;
va_start(ap,string);
val = vsprintf(buffer,string,ap);
va_end(ap);
printm(buffer);
return val;
}
int _fastcall printm (char *text) { /* Prints local and remote */
char *p;
int x;
mprint(text);
if(!sysopin) {
while ((p = strchr(text,'\x7')) != NULL)
memmove(p,&p[1],strlen(&p[1])+1);
}
x = ansi((char FAR *)text);
getxbbstime();
return x;
}
void _fastcall mprint (char *text) { /* prints remote only */
char *p;
if(!baud) return;
p = text;
while(*p) {
while(!fossil(TRANSMIT,*p)) carrchk();
p++;
}
getxbbstime();
}
/* Formatted 'printf-style' output through pd screen writer */
int _cdecl dprintf (int x,int y,char *string,...) {
static char buffer[318];
va_list ap;
va_start(ap,string);
vsprintf(buffer,string,ap);
va_end(ap);
#ifndef __SCREEN2ASM__
return(dputs(x,y,buffer));
#else
return(dputs(x,y,(char FAR *)buffer));
#endif
}
void _fastcall print_stat (void) { /* Print status line */
current_color = 7 * 16; /* reverse video */
dprintf(1,maxy,"%-31.31s \04 %31.31s\04 ",
PROGRAM_NAME,username);
}
#ifndef __SCREEN2ASM__
/*
* uses this instead of SCREEN2.ASM if all you need direct screen writes for
* is a status line. of course, you could extend this to include the other
* functions in SCREEN2.ASM rewritten in C, but if you need that much, go with
* the ASM code.
*/
int _pascal dputs (int x,int y,char *s) {
register char *p = s;
int c = (current_color << 8); /* get calc out of loop */
if(!videomethod) { /* direct screen writes */
register int FAR *v;
y--; /* dec to 0-based (call as 1-based, */
x--; /* i.e. top left of screen is 1,1) */
v = vseg + ((y * maxx) + x++); /* point v to right spot in vid RAM */
while(*p) { /* until NUL terminator... */
*v++ = (*p++ | c); /* display string to vid RAM */
}
return (int)p - (int)s; /* return displayed length */
}
else if(videomethod == 1) { /* bios screen writes */
#ifndef __TURBOC__
union REGS rg;
#endif
int xx,yy;
curr_cursor(&xx,&yy);
cursor(x,y);
while(*p) {
#ifndef __TURBOC__
rg.h.ah = 0x09; /* write char w/ attrib */
rg.h.al = *p++;
rg.h.bh = 0;
rg.h.bl = (char)c;
rg.x.cx = 0;
int86(0x10,&rg,&rg);
#else
_AH = 0x09;
_AL = *p++;
_BH = 0;
_BL = (char)c;
_CX = 0;
geninterrupt(0x10);
#endif
}
cursor(xx,yy);
return strlen(s);
}
else { /* dos screen writes, no color */
int xx,yy; /* use only as last resort */
curr_cursor(&xx,&yy);
cursor(x,y);
c = fprintf(stdout,s);
cursor(xx,yy);
return c;
}
}
#endif